package weaver.interfaces.jz.job;

import com.engine.jz.util.CommonUtil;
import com.engine.jz.util.KsUtils;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import weaver.conn.RecordSet;
import weaver.general.BaseBean;
import weaver.interfaces.schedule.BaseCronJob;

import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @version 1.0
 * @Title ecology-9
 * @Company 泛微软件
 * @CreateDate 2024/11/27
 * @Description 同步旷视门禁数据
 * @Author AdminZm
 */
public class SyncKsDoorDataJob extends BaseCronJob {

    BaseBean baseBean = new BaseBean();

    @Override
    public void execute() {
        baseBean.writeLog("SyncKsDoorDataJob start.");
        try {
            LocalDate currentDate = LocalDate.now();
            // 获取前一天的日期
            LocalDate previousDate = currentDate.minusDays(1);
            java.time.format.DateTimeFormatter formatter = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd");
            String formattedDate = previousDate.format(formatter);
            String currentDateStr = currentDate.format(formatter);
            String startTime = formattedDate + "T00:00:01+08:00";
            String endTime = currentDateStr + "T23:59:59+08:00";

            RecordSet rs = new RecordSet();
            // 获取工号与id对应
            Map<String, String> ghAndIdMap = new HashMap<>();
            rs.execute("SELECT id, loginid FROM hrmresource WHERE workcode is not null");
            while (rs.next()) {
                String id = rs.getString("id");
                String workcode = rs.getString("loginid");
                if (StringUtils.isEmpty(id) || StringUtils.isEmpty(workcode)) {
                    continue;
                }
                workcode = CommonUtil.removeLeadingZeros(workcode);
                if (StringUtils.isEmpty(workcode)) {
                    continue;
                }
                ghAndIdMap.put(workcode, id);
            }
            if (CollectionUtils.isEmpty(ghAndIdMap)) {
                baseBean.writeLog("SyncKsDoorDataJob ghAndIdMap is null.");
                return;
            }

            // 获取旷视考勤设备ip
            Set<String> ipSet = new HashSet<>();
            rs.execute("SELECT * FROM uf_kqsbdzgxgljmb WHERE sblx = 1 AND sbip is not null AND sftskqsj = 0");
            while (rs.next()) {
                String sbip = rs.getString("sbip");
                if (StringUtils.isNotEmpty(sbip)) {
                    ipSet.add(sbip);
                }
            }
            if (CollectionUtils.isEmpty(ipSet)) {
                baseBean.writeLog("SyncKsDoorDataJob ipSet is null.");
                return;
            }

            String fromType = "megvii";

            String sql = "select * from HrmScheduleSign where ( belongdate = ? OR belongdate = ? ) AND signFrom = ?";
            rs.executeQuery(sql, formattedDate, currentDateStr, fromType);
            Set<String> signSet = new HashSet<>();
            while (rs.next()) {
                String userId = rs.getString("userId");
                String signDate = rs.getString("signDate");
                String signTime = rs.getString("signTime");
                String signFrom = rs.getString("signFrom");
                if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(signDate) || StringUtils.isEmpty(signTime) ||StringUtils.isEmpty(signFrom)) {
                    continue;
                }
                if (!StringUtils.equals(signFrom, fromType)) {
                    continue;
                }
                signSet.add(userId + "_" + signDate + "_" + signTime + "_" + signFrom);
            }

            baseBean.writeLog("SyncKsDoorDataJob ipSet is:" + ipSet);
            KsUtils ksUtils = new KsUtils();
            for (String ip : ipSet) {
                try {
                    // 登陆鉴权挑战
                    String paramStr = ksUtils.loginChallenge("admin", ip);
                    Gson gson = new Gson();
                    Type type = new TypeToken<Map<String, Object>>() {
                    }.getType();
                    Map<String, Object> mapC = gson.fromJson(paramStr, type);

                    Object session_id = mapC.get("session_id");
                    Object challenge = mapC.get("challenge");
                    Object salt = mapC.get("salt");
                    if (Objects.isNull(session_id) || Objects.isNull(challenge) || Objects.isNull(salt)) {
                        return;
                    }
                    // 设备登陆
                    String loginRes = ksUtils.login(session_id.toString(), challenge.toString(), salt.toString(), ip);
                    Map<String, Object> mapIn = gson.fromJson(loginRes, type);
                    Object sessionIdNew = mapIn.get("session_id");

                    Map<String, Object> paramMap = new HashMap<>();
                    Type typeMapList = new TypeToken<List<Map<String, String>>>() {
                    }.getType();
                    int limit = 2000;
                    int offset = 0;
                    paramMap.put("limit", limit);
                    paramMap.put("sort", "asc");
                    paramMap.put("begin_time", startTime);
                    paramMap.put("end_time", endTime);

                    Set<String> needFormatSet = new HashSet<>();
                    List<List> insertList = new ArrayList<>();

                    boolean isGoing = true;
                    while (isGoing) {
                        int offsetInt = offset * limit;
                        paramMap.put("offset", offsetInt);
                        String doorStr = ksUtils.queryMj(sessionIdNew.toString(), paramMap, ip);

                        if (StringUtils.isEmpty(doorStr)) {
                            isGoing = false;
                            break;
                        }
                        Map<String, Object> doorMap = gson.fromJson(doorStr, type);
                        Object paging = doorMap.get("paging");
                        if (Objects.isNull(paging)) {
                            isGoing = false;
                            break;
                        }
                        Map<String, Object> pageMap = gson.fromJson(paging.toString(), type);
                        Object total = pageMap.get("total");
                        if (Objects.isNull(total)) {
                            isGoing = false;
                            break;
                        }
                        if (new BigDecimal(String.valueOf(offsetInt)).compareTo(new BigDecimal(total.toString())) < 0) {
                            offset = offset + 1;
                        } else {
                            isGoing = false;
                        }
                        Object data = doorMap.get("data");
                        if (Objects.isNull(data)) {
                            isGoing = false;
                            break;
                        }

                        List<Map<String, String>> mapList = (List<Map<String, String>>) data;
                        for (Map<String, String> map : mapList) {
                            String workcode = map.get("person_code");
                            String timestamp = map.get("timestamp");
                            if (StringUtils.isEmpty(timestamp) || StringUtils.isEmpty(workcode)) {
                                continue;
                            }
                            if (workcode.length() == 4 && workcode.startsWith("9")) {
                                workcode = "90" + workcode;
                            }
                            workcode = CommonUtil.removeLeadingZeros(workcode);
                            String time = CommonUtil.getDateStrFromIso8601(timestamp);
                            String id = ghAndIdMap.get(workcode);
                            if (StringUtils.isEmpty(id)) {
                                continue;
                            }
                            String[] dt = time.split(" ");
                            String rq = dt[0];
                            String sj = dt[1];
                            String keyTemp = id + "_" + rq + "_" + sj + "_" + fromType;
                            if ((!CollectionUtils.isEmpty(signSet)) && signSet.contains(keyTemp)) {
                                continue;
                            }
                            List list = new ArrayList();
                            list.add(id);
                            list.add("1");
                            list.add(rq);
                            list.add(sj);
                            list.add("1");
                            list.add(fromType);
                            list.add(rq);
                            insertList.add(list);
                            needFormatSet.add(id + "_" + rq);
                        }
                    }

                    if (!CollectionUtils.isEmpty(insertList)) {
                        String insertSql = "INSERT INTO HrmScheduleSign(userId, userType, signDate, signTime, isInCom, " +
                                "signFrom, belongdate) VALUES (?, ?, ?, ?, ?, ?, ?)";
                        rs.executeBatchSql(insertSql, insertList);
                    }
                    // 设备登出
                    ksUtils.logout(session_id.toString(), ip);
                } catch (Exception e) {
                    baseBean.writeLog("SyncKsDoorDataJob single error:" + ip + "、" + e);
                }
            }

            // 中间库方案(弃用)
            /*Set<String> needFormatSet = new HashSet<>();
            List<List> insertList = new ArrayList<>();
            Gson gson = new Gson();
            Type typeMap = new TypeToken<Map<String, String>>() {
            }.getType();
            List<String> idSet = new ArrayList<>();
            rs.executeSqlWithDataSource("select * from AttendanceData where (FLAG = 0 or flag is null ) and TIMESTAMP >= '"
                    + formattedDate + "'", "KSKQ");
            while (rs.next()) {
                String dataId = rs.getString("id");
                String data = rs.getString("data");
                if (StringUtils.isEmpty(dataId) || StringUtils.isEmpty(data)) {
                    continue;
                }
                Map<String, String> map = gson.fromJson(data, typeMap);
                String workcode = map.get("person_code");
                String timestamp = map.get("timestamp");
                if (StringUtils.isEmpty(timestamp) || StringUtils.isEmpty(workcode)) {
                    continue;
                }
                if (workcode.length() == 4 && workcode.startsWith("9")) {
                    workcode = "90" + workcode;
                }
                workcode = CommonUtil.removeLeadingZeros(workcode);
                String time = CommonUtil.getDateStrFromIso8601(timestamp);
                String id = ghAndIdMap.get(workcode);
                if (StringUtils.isEmpty(id)) {
                    continue;
                }
                String[] dt = time.split(" ");
                String rq = dt[0];
                String sj = dt[1];
                String keyTemp = id + "_" + rq + "_" + sj + "_" + fromType;
                if ((!CollectionUtils.isEmpty(signSet)) && signSet.contains(keyTemp)) {
                    continue;
                }
                List list = new ArrayList();
                list.add(id);
                list.add("1");
                list.add(rq);
                list.add(sj);
                list.add("1");
                list.add(fromType);
                list.add(rq);
                insertList.add(list);
                needFormatSet.add(id + "_" + rq);
                idSet.add(dataId);
            }

            if (!CollectionUtils.isEmpty(insertList)) {
                baseBean.writeLog("SyncKsDoorDataJob insertList size is:" + insertList.size());
                String insertSql = "INSERT INTO HrmScheduleSign(userId, userType, signDate, signTime, isInCom, " +
                        "signFrom, belongdate) VALUES (?, ?, ?, ?, ?, ?, ?)";
                rs.executeBatchSql(insertSql, insertList);
            }

            if (!CollectionUtils.isEmpty(idSet)) {
                baseBean.writeLog("SyncKsDoorDataJob idSet size is:" + idSet.size());
                int batchSize = 100; // 每个小集合的大小
                int size = idSet.size(); // 原始集合的大小
                int numberOfBatches = (int) Math.ceil((double) size / batchSize); // 划分的小集合数量
                List<List<String>> dividedLists = new ArrayList<>(); // 存储划分后的小集合

                for (int i = 0; i < numberOfBatches; i++) {
                    int fromIndex = i * batchSize;
                    int toIndex = Math.min((i + 1) * batchSize, size);
                    List<String> batch = idSet.subList(fromIndex, toIndex);
                    dividedLists.add(batch);
                }

                for (List<String> batch : dividedLists) {
                    String ids = String.join(",", batch);
                    rs.executeSqlWithDataSource("update AttendanceData set flag = 1 WHERE id in (" + ids + ")", "KSKQ");
                }
            }

            if (!CollectionUtils.isEmpty(needFormatSet)) {
                for (String key : needFormatSet) {
                    String yg = key.split("_")[0];
                    String rq = key.split("_")[1];
                    new KQFormatBiz().formatDate(yg, rq);
                    SplitActionUtil.pushOverTimeTasksAll(rq, rq, "" + yg);
                }
            }*/
        } catch (Exception e) {
            baseBean.writeLog("SyncKsDoorDataJob error:" + e);
        }
        baseBean.writeLog("SyncKsDoorDataJob end.");
    }
}
